package com.sc.nft.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dto.TeamHoldCollectionVO;
import com.sc.nft.dto.UserHoldCollectionDTO;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.*;
import com.sc.nft.entity.req.CollectionGiveDaoBatchRequest;
import com.sc.nft.entity.req.CollectionGiveDaoRequest;
import com.sc.nft.entity.vo.*;
import com.sc.nft.enums.*;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * 用户藏片表服务接口
 */
public interface UserCollectionService {

    /**
     * 获取藏品下所有的用户
     *
     * @param mallCollectionUSerDTO mallCollectionUSerDTO
     * @return MallCollectionUserVO
     */
    IPage<MallCollectionUserVO> pageUserIdByCollectionId(MallCollectionUSerDTO mallCollectionUSerDTO);


    /**
     * 商城获取用户下的藏品
     *
     * @param mallUserCollectionDTO mallUserCollectionDTO
     * @return MallUserCollectionVO
     */
    IPage<MallUserCollectionVO> pageMallUserCollection(MallUserCollectionDTO mallUserCollectionDTO);

    /**
     * 给用户添加藏品(兑换专用)
     * 1.添加藏品
     * 2.升降级逻辑(城主,居民,游客)
     * 3.刷新用户权益(化身,元婴,金丹)
     * 4.防囤逻辑(是否防囤,防囤价格计算)
     * 5.流转次数(已取消)
     * 6.流转记录
     * 7.上链逻辑
     *
     * @param userId
     * @param giveUserId
     * @param collectionId
     * @param collectionUuid
     * @param collectionImage
     * @param level
     * @param firstTitle
     * @param userCreatorId
     * @param type
     * @param boxId
     * @param boxTitle
     * @param boxImage
     * @param isOpen
     * @param productId
     * @param orderId
     * @param secondOrderId
     * @param buyAmount
     * @param numbering
     * @param fromUserCollectionId
     * @param chainUrl
     * @param id                   兑换活动id
     * @return
     */
    public UserCollection addCollectionForExchange(Long userId, Long giveUserId, Long collectionId, String collectionUuid, String collectionImage,
                                                   CollectionLevel level, String firstTitle, Long userCreatorId, ReceivedCollectionType type, Long boxId,
                                                   String boxTitle, String boxImage, Boolean isOpen, Long productId, Long orderId, Long secondOrderId,
                                                   BigDecimal buyAmount, Integer numbering, Long fromUserCollectionId, String chainUrl, AddCollectionEnum addCollectionEnum, Long id);

    /**
     * 给用户添加藏品
     * 1.添加藏品
     * 2.升降级逻辑(城主,居民,游客)
     * 3.刷新用户权益(化身,元婴,金丹)
     * 4.防囤逻辑(是否防囤,防囤价格计算)
     * 5.流转次数(已取消)
     * 6.流转记录
     * 7.上链逻辑
     *
     * @param userId
     * @param giveUserId
     * @param collectionId
     * @param collectionUuid
     * @param collectionImage
     * @param level
     * @param firstTitle
     * @param userCreatorId
     * @param type
     * @param boxId
     * @param boxTitle
     * @param boxImage
     * @param isOpen
     * @param productId
     * @param orderId
     * @param secondOrderId
     * @param buyAmount
     * @param numbering
     * @param fromUserCollectionId
     * @param chainUrl
     * @return
     */
    UserCollection addCollection(Long userId, Long giveUserId, Long collectionId, String collectionUuid, String collectionImage, CollectionLevel level, String firstTitle, Long userCreatorId, ReceivedCollectionType type,
                                 Long boxId, String boxTitle, String boxImage, Boolean isOpen, Long productId, Long orderId, Long secondOrderId, BigDecimal buyAmount, Integer numbering, Long fromUserCollectionId, String chainUrl, AddCollectionEnum addCollectionEnum, String fromUserAddress, String fromUserNickName, Boolean isDaoSource);

    /**
     * 我的藏品()
     *
     * @param isPrivilege
     * @param userId
     * @param pageNo
     * @param pageSize
     * @return
     */
    Page<MyCollectionNowVO> myCollectionNow(String isPrivilege, Long userId, int pageNo, int pageSize);

    /**
     * 我的藏品()
     *
     * @param isPrivilege
     * @param userId
     * @param pageNo
     * @param pageSize
     * @return
     */
    Page<MyCollectionVO> myCollection(String isPrivilege, Long userId, int pageNo, int pageSize);

    /**
     * 我的盲盒
     *
     * @param userId
     * @param giveStatus
     * @param pageNo
     * @param pageSize
     * @return
     */
    Page<MyBoxVO> myBox(Long userId, GiveStatusEnum giveStatus, int pageNo, int pageSize);

    /**
     * 转赠
     *
     * @param userInfo
     * @param toUserUUID
     * @param userCollectionId
     */
    void give(UserInfo userInfo, String toUserUUID, Long userCollectionId);

    /**
     * 购买
     *
     * @param secondOrder
     */
    void buy(SecondOrder secondOrder);

    void buyCollective(CollectiveOrder collectiveOrder);

    /**
     * 打开盲盒
     *
     * @param userInfo
     * @param userCollectionId
     * @return
     */
    UserCollection openBox(UserInfo userInfo, Long userCollectionId);

    /**
     * 赠送藏品记录
     *
     * @param userInfo
     * @param pageNo
     * @param pageSize
     * @return
     */
    Page<CollectionLogDTO> giveCollectionLog(UserInfo userInfo, int pageNo, int pageSize);

    /**
     * 收到的藏品记录
     *
     * @param userInfo
     * @param pageNo
     * @param pageSize
     * @return
     */
    Page<CollectionLogDTO> getCollectionLog(UserInfo userInfo, int pageNo, int pageSize);

    /**
     * 转增详情
     *
     * @param user
     * @param id
     * @return
     */
    GiveDetailsVO giveDetails(UserInfo user, Long id);

    List<NotOpenBlindBoxVO> notOpenBlindBox(Long boxId);

    /**
     * 执行转增成功
     */
    void editGiveStatus(UserCollection userCollection);

    DonationFaceVO donationFaceVerification(String url) throws IOException;

    /**
     * 转赠记录
     *
     * @param fromUserAddress
     * @param toUserAddress
     * @param transactionHash
     * @param chainUrl
     * @param pageNo
     * @param pageSize
     * @return
     */
    Page<TransferVO> transferLog(String fromUserAddress, String toUserAddress, String transactionHash, String chainUrl, int pageNo, int pageSize);

    /**
     * 用户藏品列表
     *
     * @param firstTitle
     * @param pageNo
     * @param pageSize
     * @return
     */
    Page<UserCollectionVO> userCollection(String firstTitle, int pageNo, int pageSize, Date startTime, Date endTime, String userTel);

    /**
     * 获取用户藏品到处excel
     *
     * @param firstTitle
     * @param startTime
     * @param endTime
     * @return
     */
    List<UserCollectionExcelVO> userCollectionExcel(String firstTitle, Date startTime, Date endTime, String userTel);

    /**
     * 拥有的特权藏品详情
     *
     * @param id
     */
    HavingPrivilegeCollectionDetailVO getPrivilegeCollectionDetail(Long id);

    /**
     * 上链
     *
     * @param userCollection
     */
    void mint(UserCollection userCollection);

    /**
     * 销毁
     *
     * @param userCollection
     */
    void burn(UserCollection userCollection);

    /**
     * 转增
     *
     * @param userCollection
     */
    void transfer(UserCollection userCollection);

    /**
     * 查询指定藏品id的藏品
     */
    List<UserCollection> getListByCollercitonId(Long userId, Long collectionId);


    /**
     * 查询指定藏品id的藏品
     */
    List<UserCollection> getListByIds(List<Long> ids);

    /**
     * @description: 用户某一个藏品的列表
     * @author: rdg
     * @date: 2022/8/20 13:42
     * @param: [collectionId, pageNo, pageSize]
     * @return: com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.sc.nft.entity.vo.MyCollectionListByCollectionIdVO>
     **/
    Page<MyCollectionListByCollectionIdVO> myCollectionListByCollectionId(Long collectionId, Long userId, Integer pageNo, Integer pageSize);


    /**
     * 后台市值账号专用
     *
     * @param collectionId
     * @param userId
     * @param pageNo
     * @param pageSize
     * @param lowPrice
     * @param highPrice
     * @return
     */
    Page<MyCollectionListByCollectionIdVO> maintainCollectionListByCollectionId(Long collectionId, Long userId, Integer pageNo,
                                                                                Integer pageSize, BigDecimal lowPrice,
                                                                                BigDecimal highPrice, CollectionOnConsignEnum onConsign);

    /**
     * @description: 根据收藏id查询拥有的藏品详情
     * @author: rdg
     * @date: 2022/8/20 16:19
     * @param: [id]
     * @return: com.sc.nft.entity.vo.HavingCollectionDetailVO
     **/
    HavingCollectionDetailVO getCollectionDetail(UserInfo userInfo, Long id);

    /**
     * @description: 用户藏品表生成编号
     * @author: rdg
     * @date: 2022/8/22 15:57
     * @param:
     * @return:
     */
    void generateCollectionNumber(UserCollection userCollection);

    void batchUpdateNumbering(List<UserCollection> userCollections);

    /**
     * @description: 初始化藏品编号
     * @author: rdg
     * @date: 2022/8/22 17:51
     * @param:
     * @return:
     */
    void initializationCollectionNumber();

    UserCollection getById(Long id);

    void initAnti(DigitalCollection digitalCollection);

    /**
     * 藏品详情的链信息
     *
     * @param userCollection
     * @return
     */
    CollectionChainDetailDTO getCollectionChainDetail(UserCollection userCollection);

    /**
     * 藏品链记录
     *
     * @return
     */
    Page<CollectionChainRecord> getCollectionChainRecord(Long userId, String type, int pageNo, int pageSize);

    Page<TransferVO> getAdminCollectionChainRecord(String firstTitle, String fromUserAddress, String toUserAddress, String transactionHash, Integer collectionType, Integer status, Date startTime, Date endTime, Integer pageNo, Integer pageSize);

    /**
     * 用户持有藏品
     *
     * @return
     */
    List<HoldCollectionVO> holdCollection(String collection);

    /**
     * 用户某一个藏品详情
     *
     * @param id
     * @return
     */
    SingleHoldCollection singleHoldCollection(Long id);

    /**
     * 用户分页藏品详情
     *
     * @param pageNo
     * @param pageSize
     * @param id
     * @return
     */
    Page<SingleHoldCollectionDetails> singleHoldCollectionDetailsPage(Integer pageNo, Integer pageSize, Long id);


    /**
     * 获取用户城主权益卡
     *
     * @return
     */
    Boolean getUserApplyCreatedDaoCastellanRights();

    /**
     * 查询用户藏品是否包含某个状态的藏品
     * 并且藏品是持有状态,盲盒是开启状态,并且未上架二级
     *
     * @param collectionId
     * @return
     */
    int getIsContainsAndIsHoldAndIsOpenAndOnConsignByCollectionId(Long collectionId, Long userId);

    /**
     * 查询用户藏品是否包含某个状态的藏品
     * 并且藏品是持有状态,盲盒是开启状态,并且未上架二级
     *
     * @param collectionIds
     * @return
     */
    int getIsContainsAndIsHoldAndIsOpenAndOnConsignByCollectionIds(List<Long> collectionIds, Long userId);

    /**
     * 获取用户藏品
     * 并且藏品是持有状态,盲盒是开启状态,并且未上架二级
     *
     * @param collectionId 藏品id
     * @param userId       用户id
     * @param num          数量
     * @return List<UserCollection>
     */
    List<UserCollection> getUserCollectionListByCollectionIdAndUserIdAndSize(Long collectionId, Long userId, Integer num);

    /**
     * 分页获取用户持有的藏品
     * 持有  is_hold = 1
     * 开启  is_open = 1
     * 未上架二级 on_consign = 0
     *
     * @param userId
     * @param collectionId
     * @return
     */
    Page<UserHoldCollectionVO> getPageByUserIdAndCollectionId(Long userId, Long collectionId, Integer pageNo, Integer pageSize);

    /**
     * 获取用户持有的藏品
     *
     * @param userId
     * @param collectionId
     * @return
     */
    List<UserCollection> getListByUserIdAndCollectionIdAndIds(Long userId, Long collectionId, List<Long> userCollectionIdList);

    /**
     * 修改用户藏品冻结状态
     *
     * @param id
     * @param freezingStatus
     * @return
     */
    Boolean updateFreezingStatusById(Long id, UserCollectionFreezingStatusEnum freezingStatus);

    /**
     * 批量修改用户藏品冻结状态
     *
     * @param ids
     * @param freezingStatus
     * @return
     */
    Boolean updateFreezingStatusByIds(List<Long> ids, UserCollectionFreezingStatusEnum freezingStatus);

    /**
     * 获取用户持有的藏品
     *
     * @param userId
     * @param collectionId
     * @return
     */
    Boolean whetherTheUserOwnsACollection(Long userId, Long collectionId);

    /**
     * 回收藏品
     *
     * @param userCollectionList
     */
    void recoverCollections(List<UserCollection> userCollectionList);

    /**
     * 回收藏品
     *
     * @param userCollectionList
     */
    void temporarilyRecoverCollections(List<UserCollection> userCollectionList);

    /**
     * 是否持有指定藏品
     *
     * @param userId
     * @param collectionIds
     * @return
     */
    Boolean getIsHoldCollection(Long userId, List<Long> collectionIds);

    /**
     * 获取持有指定藏品的用户列表
     *
     * @param collectionIds
     * @return
     */
    List<Long> getUserListByCollectionIds(List<Long> collectionIds);

    /**
     * 获取传入的用户id的下级持有指定藏品的用户id
     *
     * @param userId
     * @param collectionIds
     * @return
     */
    List<Long> getJuniorHoldCollectionCountByCollectionIds(Long userId, List<Long> collectionIds);


    /**
     * 查询用户持有的数量
     *
     * @param userId
     * @param collectionIds
     * @return
     */
    Integer getHoldCountByCollectionIdsAndUserId(Long userId, List<Long> collectionIds);



    /**
     * 查询用户持有的数量
     *
     * @param userIdList
     * @param collectionIds
     * @return
     */
    List<UserHoldCollectionDTO> getHoldCountByCollectionIdsAndUserIdList(List<Long> userIdList, List<Long> collectionIds);


    /**
     * 生态-销毁藏品
     *
     * @param destroyList
     */
    void ecologyDestroyCollections(List<UserCollection> destroyList);

    /**
     * 获取团对(下十级)持有某个藏品的数量
     *
     * @param collectionId
     * @return
     */
    List<TeamHoldCollectionVO> getTeamHoldCollectioncCountByCollectionId(Long collectionId, String userTel);

    /**
     * 导出网体持仓
     *
     * @param daoId
     * @param userTel
     * @param daoUserId
     * @param collectionId
     * @return
     */
    Boolean exportDaoTeamHoldCollection(Long daoId, Long daoUserId, String userTel, Long collectionId);

    /**
     * 下载网体持仓
     *
     * @param id
     * @return
     */
    List<DaoTeamHoldCollectionVO> downloadDaoTeamHoldCollection(Long id);

    /**
     * 已转让盲盒列表
     *
     * @param userId
     * @param pageNo
     * @param pageSize
     * @return
     */
    IPage<MyBoxTransferVO> myBoxTransfer(Long userId, Integer pageNo, Integer pageSize);

    /**
     * 已接收盲盒列表
     *
     * @param userId
     * @param pageNo
     * @param pageSize
     * @return
     */
    IPage<MyBoxReceiveVO> myBoxReceive(Long userId, Integer pageNo, Integer pageSize);

    /**
     * 获取用户持仓盲盒数据
     *
     * @param id
     * @param pageNo
     * @param pageSize
     * @return
     */
    IPage<BoxGroupVO> boxGroupUser(Long id, Integer pageNo, Integer pageSize);

    /**
     * 获取用户系列盲盒列表
     *
     * @param boxGroupListDTO
     * @param user
     * @return
     */
    IPage<BoxGroupListVO> boxGroupList(BoxGroupListDTO boxGroupListDTO, UserInfo user);

    /**
     * 批量转增
     *
     * @param user
     * @param giveBatchDTO
     */
    void batchGive(UserInfo user, GiveBatchDTO giveBatchDTO);

    /**
     * 转增的时候根据数量获取积分需求
     *
     * @param user
     * @param giveRequiredIntegralDTO
     * @return
     */
    GiveRequiredIntegralVO giveRequiredIntegral(UserInfo user, GiveRequiredIntegralDTO giveRequiredIntegralDTO);

    /**
     * 用户持仓（智探）
     *
     * @param userId
     * @param page
     * @param pageSize
     * @return
     */
    List<ZhiTanUserHoldVO> userHold(Long userId, Integer page, Integer pageSize);

    /**
     * 获取当前dao的最高身份名称
     *
     * @param daoId
     * @return
     */
    DaoIdentity getDaoIdentityName(Long daoId);

    /**
     * 一键导入用户藏品数据（仅盯链）
     *
     * @param userMobile
     * @param userAddress
     * @param page
     * @return
     */
    HashMap oneClickImport(String userMobile, String userAddress, Integer page);

    /**
     * 根据传入数量获取用户所有的藏品信息
     *
     * @param id
     * @param collectionId
     * @param collectionPledgeCount
     * @return
     */
    List<UserCollection> getListByUserIdAndCollectionIdAndCount(Long id, Long collectionId, Integer collectionPledgeCount);

    /**
     * 根据传入集合获取用户所有的藏品信息
     *
     * @param id
     * @param collectionId
     * @param userCollectionIdList
     * @return
     */
    List<UserCollection> getListByUserIdAndCollectionIdAndCount(Long id, Long collectionId, List<Long> userCollectionIdList);

    /**
     * 根据秘境和藏品获取最大质押份数
     *
     * @param userId
     * @param collectionId
     * @return
     */
    List<UserCollection> pledgeSecretMaxCount(Long userId, Long collectionId);

    /**
     * 获取剩余可质押数量
     *
     * @param id
     * @param collectionId
     * @return
     */
    Integer getPledgeSecretByUserIdAndCollectionId(Long id, Long collectionId);

    /**
     * 藏品转增
     *
     * @param request
     */
    void collectionGive(CollectionGiveDTO request);


    /**
     * 藏品批量转增
     *
     * @param request
     */
    void collectionBatchGive(CollectionBatchGiveDTO request);

    void collectionGiveDao(CollectionGiveDaoRequest collectionGiveDTO);

    void collectionBatchGiveDao(CollectionGiveDaoBatchRequest giveDaoBatchRequest);

    /**
     * 用户持有道具
     *
     * @param propName
     * @return
     */
    List<HoldPropVO> holdProp(String propName);

    /**
     * 用户持有道具详情
     *
     * @param id
     * @return
     */
    SingleHoldEquityProp singleHoldEquityProp(Long id);

    /**
     * 用户分页道具详情
     */
    Page<SingleHoldEquityPropDetails> singleHoldEquityPropDetailsPage(Integer pageNo, Integer pageSize, Long id);

    /**
     * 批量转增详情
     *
     * @param user
     * @param collectionId
     * @return
     */
    BatchGiveMetaWalletDetailsVO batchGiveMetaWalletDetails(UserInfo user, Long collectionId);

    /**
     * 执行跨链转增
     *
     * @param userAddr
     * @param consumeType
     * @param collectionId
     * @param userCollectionIds
     */
    void giveMetaWallet(String userAddr, Integer consumeType, Long collectionId, List<Long> userCollectionIds, UserInfo user) throws IllegalAccessException;

    /**
     * 根据用户Id获取用户持有的藏品（已上链）
     *
     * @param userId
     * @param holdCollectionIds
     * @return
     */
    List<UserCollection> getCollectionIdByUserId(Long userId, List<Long> holdCollectionIds);

    /**
     * 根据id查询 可查删除的
     *
     * @param userCollectionIdList
     * @return
     */
    List<UserCollection> getListByIdListAndDelete(List<Long> userCollectionIdList);

    /**
     * 我的版权藏品
     *
     * @param userId
     * @param pageNo
     * @param pageSize
     * @return
     */
    IPage<MyCopyrightCollectionNowVO> myCopyrightCollectionNow(Long userId, Integer pageNo, Integer pageSize);

    /**
     * 我的版权藏品详情
     *
     * @param userInfo
     * @param userCollectionId
     * @return
     */
    MyCopyrightCollectionDetailsVO myCopyrightCollectionDetails(UserInfo userInfo, Long userCollectionId);

    /**
     * 拍卖成功
     *
     * @param userCollectionId
     * @param toUserId
     * @return
     */
    void successfulAuction(Long userCollectionId, Long toUserId);


    /**
     * 获取一个用户当前正常状态可以出售的藏品id
     * @param userId
     * @param collectionId
     * @return
     */
    UserCollection getUserByCollectionIdOne(Long userId,Long collectionId);

    /**
     * 回收交易池藏品
     *
     * @param userCollection
     */
    void recoverTradingPoolCollection(UserCollection userCollection);
}
